package controllers

import (
	"AndroidBlog/models"
	"fmt"
	"github.com/PuerkitoBio/goquery"
	"github.com/astaxie/beego/httplib"
	"io"
	"math/rand"
	"strings"
	"time"
)

var (
	forgeHeaders = map[string]string{

		"Host":                      "so.csdn.net",
		"Connection":                "keep-alive",
		"Upgrade-Insecure-Requests": "1",
		"User-Agent":                "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
		"Accept":                    "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
		"Accept-Language":           "zh-CN",
		"Accept-Encoding":           "gzip, deflate, br",
	}

	// urlTitleRe = regexp.MustCompile(`img alt="(.*?)" src=`)
	// urlTitleRe = regexp.MustCompile(`<a href="(.*?)"> </a>`)
	// urlTitleRe = regexp.MustCompile(`<a href="(.*?)"> <img [^>]* alt="(.*?)" src="(.*?)" [^>]*></a>`)

	curPage       = 0
	csdnUrlFormat = "https://so.csdn.net/so/search/s.do?p=%d&q=android&t=blog&domain=&o=&s=&u=&l=&f=&rbg=0"
)

func DoCrawlCsdn(page int) (string) {
	var count = page
	strarr := []string{}
	for i := 2; i <= count; i++ {
		url := fmt.Sprintf(csdnUrlFormat, i)
		fmt.Println("url=> ", url)
		req := httplib.Get(url)
		response, e := req.Response()
		if e != nil {
			fmt.Println("get ", url, " - failed-", i)
			continue
		}
		fmt.Println("--------------------------------------------第", i, "页开始 - 共", count)
		parseInsertCsdn(response.Body)
		//strarr = append(strarr, str)
		strarr = append(strarr, string(i))
		csdnlistsleep()
	}
	str3 := strings.Join(strarr, " \r\n --- \r\n")
	return str3
}

func parseInsertCsdn(r io.Reader) {
	fmt.Println("parsecsdn")
	document, e := goquery.NewDocumentFromReader(r)
	if e != nil {
		fmt.Println("err", e)
		return
	}
	document.Find(".search-list.J_search").Each(func(i int, s *goquery.Selection) {
		//遍历
		blogs := s.Find(".flag_icon.flag_icon1").First().Text()
		var detailUrl string
		if "博客" == blogs {
			aa := s.Find("div.limit_width").Find("a")
			u, e := aa.Attr("href")
			if !e {
				return
			}
			detailUrl = u
			b := strings.Contains(detailUrl, "detail")
			if b {
				//完整的
				//title := aa.Text()
				parseDetailInsert(detailUrl)
				//fmt.Println("title:", title, " url :", detailUrl)

			}
		}
		csdnlistsleep()
	})
}

func parseDetailInsert(url string) {
	req := httplib.Get(url)
	response, e := req.Response()
	if e != nil {
		fmt.Println("get ", url, " - failed-")
		return
	}
	document, e := goquery.NewDocumentFromReader(response.Body)
	first := document.Find("div.blog-content-box").First()
	title := first.Find("h1.title-article").Text()
	crateTime := first.Find("span.time").Text()
	author := first.Find("a.follow-nickName").Text()
	link := url
	source := "csdn"
	description := ""
	fmt.Println("title:", title, " time: ", crateTime, " author: ", author, " link ", link)
	ft := TestTimeFormat(crateTime)
	art := models.Article{
		Title:       title,
		Author:      author,
		CrateTime:   ft,
		Link:        link,
		Source:      source,
		Description: description,
	}
	models.ArticleInsertOrUpdate(art)
	//author,
	//source,
	//link,
	//crateTime,
	//description,
}

func TestTimeFormat(old string) (int64) {
	//获取本地location
	toBeCharge := old                                               // "2015-01-01 00:00:00"                             //待转化为时间戳的字符串 注意 这里的小时和分钟还要秒必须写 因为是跟着模板走的 修改模板的话也可以不写
	timeLayout := "2006年01月02日 15:04:05"                            //转化所需模板
	loc, _ := time.LoadLocation("Local")                            //重要：获取时区
	theTime, _ := time.ParseInLocation(timeLayout, toBeCharge, loc) //使用模板在对应时区转化为time.time类型
	sr := theTime.Unix() * 1000                                     //转化为时间戳 类型是int64
	return sr                                                       //打印输出时间戳 1420041600
}

func csdnlistsleep() {
	x := rand.Intn(20)
	fmt.Println("随即秒->", x)
	time.Sleep(time.Duration(x) * time.Second)
}
